package cn.qdhlm.collectservice.core.component;


import cn.qdhlm.collectservice.common.Constant;
import cn.qdhlm.collectservice.common.helper.MqttHelper;
import cn.qdhlm.collectservice.common.helper.RedisHelper;
import cn.qdhlm.collectservice.common.helper.RocketMqProducer;
import cn.qdhlm.collectservice.common.util.ComUtil;
import cn.qdhlm.collectservice.common.util.JsonUtil;
import cn.qdhlm.collectservice.core.component.command.*;
import cn.qdhlm.collectservice.model.dto.CommandParamDTO;
import cn.qdhlm.collectservice.service.UtilityService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Name: Commander
 * @Description: Commander
 * @Author: jiangcs
 */
@Log4j2
@Component
public class Commander {
    @Autowired
    private UtilityService utilityService;

    /**
     * 执行 命令
     *
     * @param afn
     * @param fn
     * @param commandParamDTO
     * @return
     * @throws Exception
     */
    public String execute(String afn, String fn, CommandParamDTO commandParamDTO) throws Exception {
        log.info("execute: afn[{}], fn[{}], param[{}]", afn, fn, JsonUtil.safeJsonStr(commandParamDTO));

        // 命令序号
//        int nextSn = RedisHelper.nextSN("EX_" + commandParamDTO.getCollectorNo(), Constant.SN_MAX_COMMAND);
        int nextSn = 0;
        // 组包
        ByteBuf byteBuf = packages(nextSn, afn, fn, commandParamDTO);
        if (ComUtil.isEmpty(byteBuf) || byteBuf.readableBytes() <= 0) {
            log.error("empty byteBuf");
            return "package fail";
        }
        // 发送
        utilityService.sendCommand(nextSn, commandParamDTO.getCollectorNo(), commandParamDTO.getTerminalNo(), afn + "/" + fn, byteBuf);
        return "package success";
    }

    /**
     * 组包
     *
     * @param sn
     * @param afn
     * @param fn
     * @param commandParamDTO
     * @return
     */
    private ByteBuf packages(int sn, String afn, String fn, CommandParamDTO commandParamDTO) {
        log.info("packages: afn[{}], fn[{}]", afn, fn);

        // 数据包
        ByteBuf byteBuf = null;
        switch (afn) {
            // 确认、否认
            case "00":
                switch (fn) {
                    // 按数据单元标识确认和否认：对收到报文中的全部数据单元标识进行逐个确认/否认
                    case "f3":
                        byteBuf = CmdAfn00.f3(commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 复位命令
            case "01":
                switch (fn) {
                    // 复位重启
                    case "f5":
                        byteBuf = CmdAfn01.f5(sn, commandParamDTO);
                        break;
                    // 恢复出厂设置
                    case "f6":
                        byteBuf = CmdAfn01.f6(sn, commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 设置参数
            case "04":
                switch (fn) {
                    // 配置
                    case "f1":
                        break;
                    // 设置主站IP地址和端口
                    case "f2":
                        break;
                    // 设置采集器编号、心跳周期
                    case "f3":
                        break;
                    // 设置副站IP地址和端口
                    case "f7":
                        break;
                    // 设置终端表配置参数
                    case "f10":
                        break;
                    // 设置所有终端采集周期
                    case "f12":
                        byteBuf = CmdAfn04.f12(sn, commandParamDTO);
                        break;
                    // 采集器校时
                    case "f16":
                        byteBuf = CmdAfn04.f16(sn, commandParamDTO);
                        break;
                    // 配置信息初始化
                    case "f18":
                        byteBuf = CmdAfn04.f18(sn, commandParamDTO);
                        break;
                    // 数据解析配置初始化
                    case "f20":
                        break;
                    // 系统升级
                    case "f21":
                        byteBuf = CmdAfn04.f21(sn, commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 读参数
            case "05":
                switch (fn) {
                    // 读配置
                    case "f1":
                        break;
                    // 读取主站IP地址和端口
                    case "f2":
                        break;
                    // 读取采集器编号、心跳周期
                    case "f3":
                        break;
                    // 读取副站IP地址和端口配置
                    case "f7":
                        break;
                    // 读取终端表配置
                    case "f10":
                        break;
                    // 读取所有终端表配置
                    case "f11":
                        break;
                    // 读VAC200OC阀门配置
                    case "f13":
                        byteBuf = CmdAfn05.f13(sn, commandParamDTO);
                        break;
                    // 读取采集器时间
                    case "f16":
                        byteBuf = CmdAfn05.f16(sn, commandParamDTO);
                        break;
                    // 读取版本号
                    case "f17":
                        byteBuf = CmdAfn05.f17(sn, commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 请求1类数据
            case "0c":
                switch (fn) {
                    // 读取单个终端实时信息
                    case "f30":
                        byteBuf = CmdAfn0c.f30(sn, commandParamDTO);
                        break;
                    // 读取所有终端实时信息
                    case "f32":
                        byteBuf = CmdAfn0c.f32(sn, commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 请求2类数据
            case "0d":
                switch (fn) {
                    // 读取最近一次历史数据（单个）
                    case "f15":
                        byteBuf = CmdAfn0d.f15(sn, commandParamDTO);
                        break;
                    // 读取最近一次历史数据（所有）
                    case "f17":
                        byteBuf = CmdAfn0d.f17(sn, commandParamDTO);
                        break;
                    // 历史数据初始化(删除所有历史数据)
                    case "f20":
                        break;
                    // 删除历史数据（删除某一年所有历史）
                    case "f21":
                        break;
                    // 读取某时间历史数据（单个）
                    case "f22":
                        break;
                    // 读取某时间历史数据（所有）
                    case "f24":
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            // 阀门控制
            case "13":
                switch (fn) {
                    // 开阀门
                    case "f2":
                        byteBuf = CmdAfn13.f2(sn, commandParamDTO);
                        break;
                    // 关阀门
                    case "f3":
                        byteBuf = CmdAfn13.f3(sn, commandParamDTO);
                        break;
                    // 强制开阀
                    case "f4":
                        byteBuf = CmdAfn13.f4(sn, commandParamDTO);
                        break;
                    // 强制关阀
                    case "f5":
                        byteBuf = CmdAfn13.f5(sn, commandParamDTO);
                        break;
                    // 解锁阀门
                    case "f6":
                        byteBuf = CmdAfn13.f6(sn, commandParamDTO);
                        break;
                    // 强制设温
                    case "f7":
                        byteBuf = CmdAfn13.f7(sn, commandParamDTO);
                        break;
                    // 解锁设温
                    case "f8":
                        byteBuf = CmdAfn13.f8(sn, commandParamDTO);
                        break;
                    // 广播设温
                    case "f11":
                        byteBuf = CmdAfn13.f11(sn, commandParamDTO);
                        break;
                    // 广播解锁设温
                    case "f15":
                        byteBuf = CmdAfn13.f15(sn, commandParamDTO);
                        break;
                    // 广播强开
                    case "f18":
                        byteBuf = CmdAfn13.f18(sn, commandParamDTO);
                        break;
                    // 广播强关
                    case "f19":
                        byteBuf = CmdAfn13.f19(sn, commandParamDTO);
                        break;
                    // 广播解锁阀门
                    case "f20":
                        byteBuf = CmdAfn13.f20(sn, commandParamDTO);
                        break;
                    // 开度设置（vac200-v1）
                    case "f26":
                        byteBuf = CmdAfn13.f26(sn, commandParamDTO);
                        break;
                    // 开度范围设置（vac200）
                    case "f27":
                        byteBuf = CmdAfn13.f27(sn, commandParamDTO);
                        break;
                    // 开度上限设置（ea22，ea21）
                    case "f28":
                        byteBuf = CmdAfn13.f28(sn, commandParamDTO);
                        break;
                    // 取消远程模式（ea22）
                    case "f29":
                        byteBuf = CmdAfn13.f29(sn, commandParamDTO);
                        break;
                    // 温度范围设置（）
                    case "f30":
                        byteBuf = CmdAfn13.f30(sn, commandParamDTO);
                        break;
                    // 面板控制阀门（VAC200）
                    case "f31":
                        byteBuf = CmdAfn13.f31(sn, commandParamDTO);
                        break;
                    // 远程控制开度（VAC200）
                    case "f32":
                        byteBuf = CmdAfn13.f32(sn, commandParamDTO);
                        break;
                    // 回温自动控制开度（VAC200）
                    case "f33":
                        byteBuf = CmdAfn13.f33(sn, commandParamDTO);
                        break;
                    // 温差自动控制开度（VAC200）
                    case "f34":
                        byteBuf = CmdAfn13.f34(sn, commandParamDTO);
                        break;
                    // 启用自动调平功能（VAC200）
                    case "f35":
                        byteBuf = CmdAfn13.f35(sn, commandParamDTO);
                        break;
                    // 关闭自动调平功能（VAC200）
                    case "f36":
                        byteBuf = CmdAfn13.f36(sn, commandParamDTO);
                        break;
                    // 调节周期设定（VAC200）
                    case "f37":
                        byteBuf = CmdAfn13.f37(sn, commandParamDTO);
                        break;
                    // 采暖季设置
                    case "f38":
                        byteBuf = CmdAfn13.f38(sn, commandParamDTO);
                        break;
                    // 清洗周期
                    case "f39":
                        byteBuf = CmdAfn13.f39(sn, commandParamDTO);
                        break;
                    default:
                        log.error("match fail: afn[{}], fn[{}]", afn, fn);
                }
                break;
            default:
                log.error("match fail: afn[{}]", afn);
        }

        if (byteBuf != null) {
            // hex string
            return CmdCom.pack(byteBuf);
        }
        return null;
    }
}
